//
//  GameViewController.m
//  IssuesGame
//
//  Created by Martin Grider on 10/2/09.
//  Copyright 2009 Regents of the University of Minnesota
//

#import "GameViewController.h"
#import "Tile.h"
#import "IssuesGameAppDelegate.h"


@implementation GameViewController

// game state
@synthesize gameState, tileImages, tileSizeInPixels, marginSizeInPixels, gameBoardOffsetInPixels;

// buttons on/for the main game
@synthesize buttonLeft, buttonRight, buttonUp, buttonDown, gameView;

// stuff related to the menus (main/help/ ...etc?)
@synthesize popupView, scrollView, bigButton, littleButton, helpSubviews;

@synthesize questionView, questionTile, starImageView, correctImageView, incorrectImageView, gameOverWonImageView, gameOverLostImageView;

@synthesize startTouchPosition, currentTouchPosition;


#define HORIZONTAL_SWIPE_DRAG_MIN 20
#define VERTICAL_SWIPE_DRAG_MAX 40

#pragma mark -
#pragma mark initialization Methods

// this can do all the work to set up our game (the first time)...
- (void)setupInitialGameState:(GameState *)gameStateObject {
	// first set our gameState property from the one we've passed in
	[self setGameState:gameStateObject];
	[gameState setAskingQuestion:NO];
	respondToTouch = YES;
}


#pragma mark -
#pragma mark drawing Methods

// draw all our "dynamic" content from the gameState object
- (void)drawFromGameStateWithOption:(BOOL)allTiles {
	
	[gameState setAskingQuestion:NO];
	[gameBoardView setUserInteractionEnabled:YES];
	
	// various text labels
	//NSLog([gameState title]);
	[(UILabel *)[[self view] viewWithTag:372] setText:[gameState title]];
	//NSLog(@"%i", [gameState score]);
	[(UILabel *)[[self view] viewWithTag:777] setText:[NSString stringWithFormat:@"%i", [gameState score]]];
	
	if( allTiles )
		[self drawGameTilesFromGameState];
	else {
		[self drawGameTileForX:[gameState playerPrevX] forY:[gameState playerPrevY]];
		[self drawGameTileForX:[gameState playerX] forY:[gameState playerY]];
	}
	
	// draw the player indicator
	[self drawGamePlayerImageFromGameState];

	// flash the movement arrows
	[self drawMovementArrowsAndFade];
	
	// draw question if necessary
	[self handleCurrentPlayerLocation];
	
	respondToTouch = YES;
}


- (void)drawMovementArrowsAndFade {
	[[self view] bringSubviewToFront:gameBoardView];
	
	if ( [gameState playerCanMoveUp] ) {
		[gameBoardView bringSubviewToFront:buttonUp];
		[buttonUp setAlpha:1];
	}
	else
		[gameBoardView sendSubviewToBack:buttonUp];

	if ( [gameState playerCanMoveDown] ) {
		[gameBoardView bringSubviewToFront:buttonDown];
		[buttonDown setAlpha:1];
	}
	else
		[gameBoardView sendSubviewToBack:buttonDown];

	if ( [gameState playerCanMoveLeft] ) {
		[gameBoardView bringSubviewToFront:buttonLeft];
		[buttonLeft setAlpha:1];
	}
	else
		[gameBoardView sendSubviewToBack:buttonLeft];

	if ( [gameState playerCanMoveRight] ) {
		[gameBoardView bringSubviewToFront:buttonRight];
		[buttonRight setAlpha:1];
	}
	else
		[gameBoardView sendSubviewToBack:buttonRight];
		
	[UIView beginAnimations:nil context:nil];
	[UIView setAnimationDuration:kArrowFadeAnimationInterval];
	[buttonUp    setAlpha:kQuestionArrowMinimumAlpha];
	[buttonDown  setAlpha:kQuestionArrowMinimumAlpha];
	[buttonLeft  setAlpha:kQuestionArrowMinimumAlpha];
	[buttonRight setAlpha:kQuestionArrowMinimumAlpha];
	[UIView commitAnimations];
}


- (void)drawGamePlayerImageFromGameState {
	int offsetX = (tileSizeInPixels * [gameState playerX]) + marginSizeInPixels;
	int offsetY = (tileSizeInPixels * [gameState playerY]) + gameBoardOffsetInPixels;

	//NSLog(@"playerX: %i, playerY: %i, tileSizeInPixels: %i, gameBoardOffsetInPixels: %i, offsetX: %i, offsetY: %i", [gameState playerX], [gameState playerY], tileSizeInPixels, gameBoardOffsetInPixels, offsetX, offsetY);

	// check for starting state
	if ( [gameState playerX] == 0 && [gameState playerY] == ([gameState size] -1) ) {
		offsetX = offsetX - (marginSizeInPixels);
	}
	else {
		// Change the tile underneath to one of the white-capped ones: tile_overlay.png
		UIImageView *tileImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"tile_overlay.png"]];
		[tileImageView setBackgroundColor:[UIColor whiteColor]];
		[tileImageView setFrame:CGRectMake(offsetX, offsetY, tileSizeInPixels, tileSizeInPixels)];
		[gameBoardView addSubview:tileImageView];
		[gameBoardView bringSubviewToFront:tileImageView];
		[tileImages addObject:tileImageView];
		[tileImageView release];
	}
	[starImageView setFrame:CGRectMake(offsetX, offsetY, tileSizeInPixels, tileSizeInPixels)];
	[gameBoardView bringSubviewToFront:starImageView];
}


- (void)drawGameTilesFromGameState {
	int			tileIndex;
	int			gameSize = [gameState size];
	NSString	*perspective;
	BOOL		isQuestionTile;
	UIImage		*perspectiveImage;
	int			x, y, frameX, frameY, frameWidth, frameHeight;
	int			maxIndex = ( gameSize -1 );

	if ( [tileImages count] > 0 )
		[self releaseGameTileImages];
		
	for ( y=0; y <= maxIndex; y++ ) {
		frameY = ( y * tileSizeInPixels ) + gameBoardOffsetInPixels;

		for ( x=0; x <= maxIndex; x++ ) {

			// all the "information" needed about each tile is set here
			//currentTile = [gameState tileAtRow:y andColumn:x];
			tileIndex   = (y * gameSize) + x;
			perspective = [[[gameState tiles] objectAtIndex:tileIndex] valueForKey:kTilePerspective];
			frameX      = ( x * tileSizeInPixels ) + marginSizeInPixels;
			frameWidth  = tileSizeInPixels;
			frameHeight = tileSizeInPixels;

			// draw our end tile
			if ( x == maxIndex && y == 0 ) {
				isQuestionTile   = NO;
				frameY           = frameY - marginSizeInPixels;
				frameWidth       = 320 - frameX;
				frameHeight      = tileSizeInPixels + marginSizeInPixels;
				perspectiveImage = [UIImage imageNamed:@"tile_finish.png"];
				//NSLog(@"end tile");
			}
			// draw our start tile
			else if ( x == 0 && y == maxIndex ) {
				isQuestionTile   = NO;
				frameX           = frameX - marginSizeInPixels;
				frameWidth       = tileSizeInPixels + marginSizeInPixels;
				frameHeight      = 325 - frameY;
				perspectiveImage = [UIImage imageNamed:@"tile_start.png"];
				//NSLog(@"start tile with frameWidth: %i, frameHeight: %i", frameWidth, frameHeight);
			}
			else if ( [perspective isEqualToString:kTilePerspectiveBlank] ) {
				isQuestionTile   = NO;
				perspectiveImage = [UIImage imageNamed:@"tile_empty.png"];
			}
			else {
				isQuestionTile   = YES;
				perspectiveImage = [[gameState perspectiveImages] valueForKey:perspective];
				if ( perspectiveImage == nil ) {
					NSLog(@"image is nil for perspective: %@", perspective);
				}
			}

			//NSLog(@"drawing tile x: %i y: %i (at x: %i y: %i) question: %@ named:%@", x, y, frameX, frameY, (isQuestionTile ? @"YES":@"NO"), perspective);

			// finally, draw the tile at the index
			UIImageView *tileImageView = [[UIImageView alloc] initWithImage:perspectiveImage];
			[tileImageView setFrame:CGRectMake(frameX, frameY, frameWidth, frameHeight)];
			[gameBoardView addSubview:tileImageView];
			[tileImages addObject:tileImageView];
			[tileImageView release];

			// if this is a standard tile, draw the gloss
			if ( isQuestionTile ) {
				UIImageView *tileGlossView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"tile_overlay.png"]];
				[tileGlossView setFrame:CGRectMake(frameX, frameY, frameWidth, frameHeight)];
				[gameBoardView addSubview:tileGlossView];
				[tileImages addObject:tileGlossView];
				[tileGlossView release];
			}
		}
	}

}


// Yes, this is a bit redundant
- (void)drawGameTileForX:(int)tileX forY:(int)tileY {
	int tileIndex;
	int gameSize = [gameState size];
	NSString *perspective;
	BOOL isQuestionTile;
	UIImage *perspectiveImage;
	int x, y, frameX, frameY, frameWidth, frameHeight;
	int maxIndex = ( gameSize -1 );

	y = tileY;
	x = tileX;
		
	frameY = ( y * tileSizeInPixels ) + gameBoardOffsetInPixels;
	
	// all the "information" needed about each tile is set here
	//currentTile = [gameState tileAtRow:y andColumn:x];
	tileIndex   = (y * gameSize) + x;
	perspective = [[[gameState tiles] objectAtIndex:tileIndex] valueForKey:kTilePerspective];
	frameX      = ( x * tileSizeInPixels ) + marginSizeInPixels;
	frameWidth  = tileSizeInPixels;
	frameHeight = tileSizeInPixels;
	
	// draw our end tile
	if ( x == maxIndex && y == 0 ) {
		isQuestionTile   = NO;
		frameY           = frameY - marginSizeInPixels;
		frameWidth       = 320 - frameX;
		frameHeight      = tileSizeInPixels + marginSizeInPixels;
		perspectiveImage = [UIImage imageNamed:@"tile_finish.png"];
		//NSLog(@"end tile");
	}
	// draw our start tile
	else if ( x == 0 && y == maxIndex ) {
		isQuestionTile   = NO;
		frameX           = frameX - marginSizeInPixels;
		frameWidth       = tileSizeInPixels + marginSizeInPixels;
		frameHeight      = 325 - frameY;
		perspectiveImage = [UIImage imageNamed:@"tile_start.png"];
		//NSLog(@"start tile with frameWidth: %i, frameHeight: %i", frameWidth, frameHeight);
	}
	else if ( [perspective isEqualToString:kTilePerspectiveBlank] ) {
		isQuestionTile   = NO;
		perspectiveImage = [UIImage imageNamed:@"tile_empty.png"];
	}
	else {
		isQuestionTile   = YES;
		perspectiveImage = [[gameState perspectiveImages] valueForKey:perspective];
		if ( perspectiveImage == nil ) {
			NSLog(@"image is nil for perspective: %@", perspective);
		}
	}
	
	//NSLog(@"drawing tile x: %i y: %i (at x: %i y: %i) question: %@ named:%@", x, y, frameX, frameY, (isQuestionTile ? @"YES":@"NO"), perspective);
	
	// finally, draw the tile at the index
	UIImageView *tileImageView = [[UIImageView alloc] initWithImage:perspectiveImage];
	[tileImageView setFrame:CGRectMake(frameX, frameY, frameWidth, frameHeight)];
	[gameBoardView addSubview:tileImageView];
	[tileImages addObject:tileImageView];
	[tileImageView release];
	
	// if this is a standard tile, draw the gloss
	if ( isQuestionTile ) {
		UIImageView *tileGlossView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"tile_overlay.png"]];
		[tileGlossView setFrame:CGRectMake(frameX, frameY, frameWidth, frameHeight)];
		[gameBoardView addSubview:tileGlossView];
		[tileImages addObject:tileGlossView];
		[tileGlossView release];
	}
	//NSLog(@"drew tile.");
}


#pragma mark -
#pragma mark view Methods

// programatic view hierarchy
- (void)loadView {

	// init the main view
    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
	self.view = view;
    [view release];

	// some images and buttons
	UIImageView *bgHeader = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"bg_header.png"]];
	[bgHeader setFrame:CGRectMake(0, 0, 320, 135)];
	[self.view addSubview:bgHeader];
	[bgHeader release];

	NSString *headerLogoPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"gamedocs/logo_topic_tiles.png"];
	UIImageView *headerLogo = [[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:headerLogoPath]];
	[headerLogo setFrame:CGRectMake(11, 8, 52, 52)];
	[self.view addSubview:headerLogo];
	[headerLogo release];

	int backgroundImageYOffset = 135;
	gameBoardView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"background.png"]];
	[gameBoardView setFrame:CGRectMake(0, backgroundImageYOffset, 320, 324)];
	[self.view addSubview:gameBoardView];
	[gameBoardView release];

	gameBoardOffsetInPixels = 4;

	UILabel *title = [[UILabel alloc] initWithFrame:CGRectMake(0, 20, 320, 25)];
	[title setText:@"TopicTiles"];
	[title setTextColor:[UIColor whiteColor]];
	[title setBackgroundColor:[UIColor clearColor]];
	[title setTextAlignment:UITextAlignmentCenter];
	[title setFont:[UIFont fontWithName:@"Helvetica-Bold" size:22]];
	[self.view addSubview:title];
	[title release];

	// label for the topic title (tag 372)
	UILabel *topicLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 45, 320, 20)];
	[topicLabel setTextColor:[UIColor whiteColor]];
	[topicLabel setBackgroundColor:[UIColor clearColor]];
	[topicLabel setTextAlignment:UITextAlignmentCenter];
	[topicLabel setFont:[UIFont fontWithName:@"Helvetica-Bold" size:12]];
	[topicLabel setTag:372];
	[self.view addSubview:topicLabel];
	[topicLabel release];

	// gameView
	gameView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
	[self.view addSubview:gameView];
	tileImages = [[NSMutableArray alloc] initWithCapacity:1];

	// figure out the width of our pixels
	marginSizeInPixels = 3;
	int initialGameBoardSize = 320 - ( marginSizeInPixels * 2 );  // 314 = 320 - 3 pixel margins
	
	tileSizeInPixels = 6;  // 6 px minimum size
	while ( ( ( tileSizeInPixels +1 ) * [gameState size] ) < initialGameBoardSize )
		tileSizeInPixels++;

	// view to "contain" the game's score tag
	UIView *scoreBounds = [[UIView alloc] initWithFrame:CGRectMake(166, 81, 88, 43)];
	[scoreBounds setClipsToBounds:YES];
	[scoreBounds setTag:776];
	[gameView addSubview:scoreBounds];
	[scoreBounds release];

	// label for the game's score (tag 777)
	UILabel *scoreLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 4, 70, 40)];
	[scoreLabel setText:@"000"];
	[scoreLabel setTextColor:[UIColor blackColor]];
	[scoreLabel setBackgroundColor:[UIColor clearColor]];
	[scoreLabel setTextAlignment:UITextAlignmentRight];
	[scoreLabel setFont:[UIFont fontWithName:@"Helvetica-Bold" size:38]];
	[scoreLabel setTag:777];
	[[gameView viewWithTag:776] addSubview:scoreLabel];
	[scoreLabel release];
	
	// buttons
	UIButton *pauseButton = [[UIButton buttonWithType:UIButtonTypeCustom] retain];
	[pauseButton setImage:[UIImage imageNamed:@"btn_pause.png"] forState:UIControlStateNormal];
	[pauseButton setFrame:CGRectMake(-2, 72, 72, 61)];
	[pauseButton setBackgroundColor:[UIColor clearColor]];
	[pauseButton addTarget:self action:@selector(openPauseMenu) forControlEvents:UIControlEventTouchUpInside];
	[gameView addSubview:pauseButton];
	[pauseButton release];

	UIButton *helpButton = [[UIButton buttonWithType:UIButtonTypeCustom] retain];
	[helpButton setImage:[UIImage imageNamed:@"btn_help.png"] forState:UIControlStateNormal];
	[helpButton setFrame:CGRectMake(250, 72, 72, 61)];
	[helpButton setBackgroundColor:[UIColor clearColor]];
	[helpButton addTarget:self action:@selector(openHelpMenu) forControlEvents:UIControlEventTouchUpInside];
	[gameView addSubview:helpButton];
	[helpButton release];

	// instantiate the help subViews
	[self loadHelpSubViews];

	// the movement arrows
	buttonLeft = [[UIButton buttonWithType:UIButtonTypeCustom] retain];
	[buttonLeft setImage:[UIImage imageNamed:@"arrow_left.png"] forState:UIControlStateNormal];
	[buttonLeft setFrame:CGRectMake(9, 95, 88, 145)];
	[buttonLeft setBackgroundColor:[UIColor clearColor]];
	[buttonLeft addTarget:self action:@selector(moveLeft) forControlEvents:UIControlEventTouchUpInside];
	[gameBoardView addSubview:buttonLeft];

	buttonRight = [[UIButton buttonWithType:UIButtonTypeCustom] retain];
	[buttonRight setImage:[UIImage imageNamed:@"arrow_right.png"] forState:UIControlStateNormal];
	[buttonRight setFrame:CGRectMake(225, 95, 88, 145)];
	[buttonRight setBackgroundColor:[UIColor clearColor]];
	[buttonRight addTarget:self action:@selector(moveRight) forControlEvents:UIControlEventTouchUpInside];
	[gameBoardView addSubview:buttonRight];

	buttonUp = [[UIButton buttonWithType:UIButtonTypeCustom] retain];
	[buttonUp setImage:[UIImage imageNamed:@"arrow_top.png"] forState:UIControlStateNormal];
	[buttonUp setFrame:CGRectMake(87, 11, 145, 88)];
	[buttonUp setBackgroundColor:[UIColor clearColor]];
	[buttonUp addTarget:self action:@selector(moveUp) forControlEvents:UIControlEventTouchUpInside];
	[gameBoardView addSubview:buttonUp];

	buttonDown = [[UIButton buttonWithType:UIButtonTypeCustom] retain];
	[buttonDown setImage:[UIImage imageNamed:@"arrow_bottom.png"] forState:UIControlStateNormal];
	[buttonDown setFrame:CGRectMake(87, 231, 145, 88)];
	[buttonDown setBackgroundColor:[UIColor clearColor]];
	[buttonDown addTarget:self action:@selector(moveDown) forControlEvents:UIControlEventTouchUpInside];
	[gameBoardView addSubview:buttonDown];

	// star image for player location
	starImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"star.png"]];
	// we'll set the frame later...
	[gameBoardView addSubview:starImageView];


	// initialize the popup
	// the background of this popup type view
	popupView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"bg_overlay_large.png"]];
	[popupView setFrame:CGRectMake(0, 70, 320, 390)];
	[popupView setBackgroundColor:[UIColor clearColor]];
	[popupView setHidden:YES];
	[self.view addSubview:popupView];
	
	scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(42, 42, 236, 236)];
	[popupView addSubview:scrollView];
	
	bigButton = [[UIButton buttonWithType:UIButtonTypeCustom] retain];
	[bigButton setBackgroundImage:[UIImage imageNamed:@"btn_blue.png"] forState:UIControlStateNormal];
	[bigButton setFrame:CGRectMake(43, 235, 234, 50)];
	[bigButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
	bigButton.titleLabel.font = [UIFont fontWithName:@"Helvetica-Bold" size:18];
	[bigButton setHidden:YES];
	[popupView addSubview:bigButton];

	littleButton = [[UIButton buttonWithType:UIButtonTypeCustom] retain];
	[littleButton setBackgroundImage:[UIImage imageNamed:@"btn_grey.png"] forState:UIControlStateNormal];
	[littleButton setFrame:CGRectMake(43, 324, 234, 26)];
	[littleButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
	littleButton.titleLabel.font = [UIFont fontWithName:@"Helvetica-Bold" size:12];
	[littleButton setHidden:YES];
	[popupView addSubview:littleButton];


	// initialize the questionView
	questionView = [[QuestionView alloc] initWithFrame:CGRectMake(0, 136, 320, 324) andController:self];
	[questionView setHidden:YES];
	[self.view addSubview:questionView];

	questionAnsweredViewIsDisplayed = NO;

	// correct and incorrect images
	correctImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"correct.png"]];
	[correctImageView setFrame:CGRectMake(0, 0, 320, 460)];
	[correctImageView setBackgroundColor:[UIColor clearColor]];
	[correctImageView setHidden:YES];
	[self.view addSubview:correctImageView];

	incorrectImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"incorrect.png"]];
	[incorrectImageView setFrame:CGRectMake(0, 0, 320, 460)];
	[incorrectImageView setBackgroundColor:[UIColor clearColor]];
	[incorrectImageView setHidden:YES];
	[self.view addSubview:incorrectImageView];


	// game over (won) view
	gameOverWonImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"congrats.png"]];
	[gameOverWonImageView setFrame:CGRectMake(0, 0, 320, 460)];
	[gameOverWonImageView setBackgroundColor:[UIColor clearColor]];
	[gameOverWonImageView setHidden:YES];
	[self.view addSubview:gameOverWonImageView];

	// game over (lost) view
	gameOverLostImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"game_over.png"]];
	[gameOverLostImageView setFrame:CGRectMake(0, 0, 320, 460)];
	[gameOverLostImageView setBackgroundColor:[UIColor clearColor]];
	[gameOverLostImageView setHidden:YES];
	[self.view addSubview:gameOverLostImageView];
	
	UILabel *endScoreLabel = [[UILabel alloc] initWithFrame:CGRectMake(125, 263, 70, 40)];
	[endScoreLabel setText:@"000"];
	[endScoreLabel setTextColor:[UIColor blackColor]];
	[endScoreLabel setBackgroundColor:[UIColor clearColor]];
	[endScoreLabel setTextAlignment:UITextAlignmentCenter];
	[endScoreLabel setFont:[UIFont fontWithName:@"Helvetica-Bold" size:38]];
	[endScoreLabel setTag:777];
	[gameOverWonImageView addSubview:endScoreLabel];
	[endScoreLabel release];

	gameOverWonViewIsDisplayed = NO;
}


// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];
	[self drawFromGameStateWithOption:YES];
}


- (void)loadHelpSubViews {
	helpSubviews = [[NSMutableArray alloc] initWithCapacity:1];

	int totalHeight = 0;
	int totalWidth  = 236;

	UILabel *title = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, totalWidth, 25)];
	[title setText:@"Instructions"];
	[title setTextColor:[UIColor colorWithRed:kDefaultTextColorRed green:kDefaultTextColorGreen blue:kDefaultTextColorBlue alpha:1.0]];
	[title setBackgroundColor:[UIColor clearColor]];
	[title setTextAlignment:UITextAlignmentCenter];
	[title setFont:[UIFont fontWithName:@"Helvetica-Bold" size:22]];
	[helpSubviews addObject:title];
	[title release];
	totalHeight = totalHeight + 25;

	// small margin
	totalHeight = totalHeight + 10;

	// general help text
	NSString *helpText = @"Topic Tiles is played by clicking on one of the directional arrows to move your cursor (the star) around the gameboard.\n\n";
	helpText = [helpText stringByAppendingFormat:@"Every time you move %i points will be deducted from your score. ", kGameScoreMovementDecrement];
	helpText = [helpText stringByAppendingString:@"When you land on a topic tile, a question in that topic will be displayed. "];
	helpText = [helpText stringByAppendingFormat:@"If you select the correct answer, %i points will added to your score. \n\n", kGameScoreQuestionCorrectIncrement];
	helpText = [helpText stringByAppendingString:@"If you run out of points, that's GAME OVER! "];

	UIFont *textFont = [UIFont fontWithName:@"Helvetica-Bold" size:12];

	CGSize textSize = [helpText sizeWithFont:textFont constrainedToSize:CGSizeMake(totalWidth, 236) lineBreakMode:UILineBreakModeWordWrap];

	UILabel *textLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, totalHeight, totalWidth, textSize.height)];
	[textLabel setText:helpText];
	[textLabel setLineBreakMode:UILineBreakModeWordWrap];
	[textLabel setNumberOfLines:0];
	[textLabel setTextColor:[UIColor colorWithRed:kDefaultTextColorRed green:kDefaultTextColorGreen blue:kDefaultTextColorBlue alpha:1.0]];
	[textLabel setBackgroundColor:[UIColor clearColor]];
	[textLabel setTextAlignment:UITextAlignmentLeft];
	[textLabel setFont:textFont];
	[helpSubviews addObject:textLabel];
	[textLabel release];
	totalHeight = totalHeight + textSize.height;

	// bigger margin
	totalHeight = totalHeight + 15;

	// Topics
	UILabel *ttitle = [[UILabel alloc] initWithFrame:CGRectMake(0, totalHeight, totalWidth, 25)];
	[ttitle setText:@"Topics"];
	[ttitle setTextColor:[UIColor colorWithRed:kDefaultTextColorRed green:kDefaultTextColorGreen blue:kDefaultTextColorBlue alpha:1.0]];
	[ttitle setBackgroundColor:[UIColor clearColor]];
	[ttitle setTextAlignment:UITextAlignmentCenter];
	[ttitle setFont:[UIFont fontWithName:@"Helvetica-Bold" size:22]];
	[helpSubviews addObject:ttitle];
	[ttitle release];
	totalHeight = totalHeight + 25;

	// small margin
	totalHeight = totalHeight + 10;
}


#pragma mark -
#pragma mark player motion methods


- (void)moveLeft {
	if ( [gameState playerCanMoveLeft] && respondToTouch ) {
		//NSLog(@"moving left...");
		[self doMoveWithX:-1 WithY:0];
	}
}

- (void)moveRight {
	if ( [gameState playerCanMoveRight] && respondToTouch ) {
		//NSLog(@"moving right...");
		[self doMoveWithX:+1 WithY:0];
	}
}

- (void)moveUp {
	if ( [gameState playerCanMoveUp] && respondToTouch ) {
		//NSLog(@"moving up...");
		[self doMoveWithX:0 WithY:-1];
	}
}


- (void)moveDown {
	if ( [gameState playerCanMoveDown] && respondToTouch ) {
		//NSLog(@"moving down...");
		[self doMoveWithX:0 WithY:+1];
	}
}

- (void)doMoveWithX: (int) xStep WithY: (int) yStep {
	[gameState setPlayerPrevX:[gameState playerX]];
	[gameState setPlayerPrevY:[gameState playerY]];
	if( xStep) [gameState setPlayerX:([gameState playerX] + xStep)];
	if( yStep) [gameState setPlayerY:([gameState playerY] + yStep)];
	[self animatePlayerMotion];
}

- (void)animatePlayerMotion {
	// make sure we can't move twice in a row
	respondToTouch = NO;

	// decrement the player score
	[self changePlayerScore:-kGameScoreMovementDecrement];

	int offsetX = (tileSizeInPixels * [gameState playerX]) + marginSizeInPixels;
	int offsetY = (tileSizeInPixels * [gameState playerY]) + gameBoardOffsetInPixels;

	//NSLog(@"playerX: %i, playerY: %i, tileSizeInPixels: %i, gameBoardOffsetInPixels: %i, offsetX: %i, offsetY: %i", [gameState playerX], [gameState playerY], tileSizeInPixels, gameBoardOffsetInPixels, offsetX, offsetY);

	// check for starting state
	if ( [gameState playerX] == 0 && [gameState playerY] == ([gameState size] -1) ) {
		offsetX = offsetX - (marginSizeInPixels);
	}
	// check for ending state
	else if ( [gameState playerY] == 0 && [gameState playerX] == ([gameState size] -1) ) {
		offsetX = offsetX + (marginSizeInPixels);
	}

	[UIView beginAnimations:nil context:nil];
	[UIView setAnimationDuration:kPlayerStarAnimationInterval];
	[UIView setAnimationDelegate:self];
	[UIView setAnimationDidStopSelector:@selector(handleCurrentPlayerLocation)];
	[starImageView setFrame:CGRectMake(offsetX, offsetY, tileSizeInPixels, tileSizeInPixels)];
	[UIView commitAnimations];
}

- (void)handleCurrentPlayerLocation {	
	respondToTouch = YES;
	
	if ( [gameState score] <= 0 ) {
		[self openGameOverLost];
		return;
	}
	
	//NSLog(@"Handling current player location");
	[self setQuestionTile:[gameState tileAtCurrentPlayerLocation]];
	
	if ( [[questionTile perspective] isEqualToString:kTilePerspectiveFinish] ) {
		// game over, you win!
		[self openGameOverWon];
		return;
	}
	else if ( ! [questionTile isQuestionTile] ) {
		[self drawGameTileForX:[gameState playerPrevX] forY:[gameState playerPrevY]];
		[self drawGameTileForX:[gameState playerX] forY:[gameState playerY]];
		[self drawGamePlayerImageFromGameState];
		[self drawMovementArrowsAndFade];
		return;
	}
	
	//NSLog(@"yes, actually displaying a question...");
	[questionView loadQuestionFromTile:questionTile];
	[questionView setUserInteractionEnabled:YES];
	[gameBoardView setUserInteractionEnabled:NO];
	[[self view] bringSubviewToFront:questionView];
	
	[questionView setHidden:NO];
	[gameState setAskingQuestion:YES];
}


#pragma mark -
#pragma mark player score methods

- (void)changePlayerScore:(int)modifier {
	int newScore = [gameState score] + modifier;

	// basic strategy is to create two new labels, a "dummy" score label that will roll down, 
	// and a modifier label that will also roll down. The main score label will be positioned above
	// so that it can also roll down back into its original resting place.
	UILabel *dummyLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 4, 70, 40)];
	[dummyLabel setText:[NSString stringWithFormat:@"%i",[gameState score]]];
	[dummyLabel setTextColor:[UIColor blackColor]];
	[dummyLabel setBackgroundColor:[UIColor clearColor]];
	[dummyLabel setTextAlignment:UITextAlignmentRight];
	[dummyLabel setFont:[UIFont fontWithName:@"Helvetica-Bold" size:38]];
	[dummyLabel setTag:778];
	[[gameView viewWithTag:776] addSubview:dummyLabel];
	[dummyLabel release];

	UILabel *modifierLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, -40, 70, 40)];
	[modifierLabel setText:[NSString stringWithFormat:@"%i",modifier]];
	if ( modifier > 0 ) {
		[modifierLabel setTextColor:[UIColor greenColor]];
	}
	else {
		[modifierLabel setTextColor:[UIColor redColor]];
	}
	[modifierLabel setBackgroundColor:[UIColor clearColor]];
	[modifierLabel setTextAlignment:UITextAlignmentRight];
	[modifierLabel setFont:[UIFont fontWithName:@"Helvetica-Bold" size:38]];
	[modifierLabel setTag:779];
	[[gameView viewWithTag:776] addSubview:modifierLabel];
	[modifierLabel release];

	[[gameView viewWithTag:777] setFrame:CGRectMake(0, -80, 70, 40)];

	// set the actual score in the gamestate
	[gameState setScore:newScore];
	[(UILabel *)[gameView viewWithTag:777] setText:[NSString stringWithFormat:@"%i",newScore]];

	// animations here...
	[UIView beginAnimations:nil context:nil];
	[UIView setAnimationDuration:kPlayerStarAnimationInterval];
	[UIView setAnimationDelegate:self];
	[UIView setAnimationDidStopSelector:@selector(changePlayerScoreAnimationEnds)];

	[[gameView viewWithTag:777] setFrame:CGRectMake(0, 4, 70, 40)];
	[[gameView viewWithTag:778] setFrame:CGRectMake(0, 85, 70, 40)];
	[[gameView viewWithTag:779] setFrame:CGRectMake(0, 45, 70, 40)];

	[UIView commitAnimations];
}


- (void)changePlayerScoreAnimationEnds {
	[[gameView viewWithTag:778] removeFromSuperview];
	[[gameView viewWithTag:779] removeFromSuperview];
}


#pragma mark -
#pragma mark view switching methods


- (void)startNewGame {
	//NSLog(@"starting a new game...");
	[self releaseGameTileImages];
	[[[UIApplication sharedApplication] delegate] startNewGame];
	[self drawFromGameStateWithOption:YES];
	[self closeQuestionView];
	[self closePauseMenu];
}


- (void)openCorrectAnswerView {
	//NSLog(@"correct answer popping up...");

	[correctImageView setHidden:NO];

	questionAnsweredViewIsDisplayed = YES;
	[questionView setUserInteractionEnabled:NO];
	[questionTile correctlyAnswered];
	[[self view] bringSubviewToFront:correctImageView];
}


- (void)openIncorrectAnswerView {
	//NSLog(@"incorrect answer popping up...");

	[incorrectImageView setHidden:NO];

	questionAnsweredViewIsDisplayed = YES;
	[questionView setUserInteractionEnabled:NO];
	[questionTile incorrectlyAnswered];
	[[self view] bringSubviewToFront:incorrectImageView];
}


- (void)closeQuestionView {
	//NSLog(@"closing questionView...");
	[gameState setAskingQuestion:NO];

	[questionView setHidden:YES];
	[questionView setUserInteractionEnabled:NO];

	[correctImageView setHidden:YES];
	[incorrectImageView setHidden:YES];

	[gameBoardView setUserInteractionEnabled:YES];
	[self drawFromGameStateWithOption:NO];
}


- (void)openPauseMenu {
	//NSLog(@"pausing...");

	[popupView setUserInteractionEnabled:YES];
	[gameView setUserInteractionEnabled:NO];

	[popupView setHidden:NO];

	[popupView bringSubviewToFront:littleButton];
	[[self view] bringSubviewToFront:popupView];
	[littleButton setTitle:@"Return To Game" forState:UIControlStateNormal];
	[littleButton setHidden:NO];
	[littleButton addTarget:self action:@selector(closePauseMenu) forControlEvents:UIControlEventTouchUpInside];

	[popupView bringSubviewToFront:bigButton];
	[bigButton setTitle:@"Start New Game" forState:UIControlStateNormal];
	[bigButton setHidden:NO];
	[bigButton addTarget:self action:@selector(startNewGame) forControlEvents:UIControlEventTouchUpInside];

	UILabel *title = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 236, 25)];
	[title setText:@"Paused"];
	[title setTextColor:[UIColor colorWithRed:kDefaultTextColorRed green:kDefaultTextColorGreen blue:kDefaultTextColorBlue alpha:1.0]];
	//[title setBackgroundColor:[UIColor clearColor]];
	[title setTextAlignment:UITextAlignmentCenter];
	[title setFont:[UIFont fontWithName:@"Helvetica-Bold" size:22]];
	[title setTag:101010];
	[scrollView addSubview:title];
	[title release];
}


- (void)closePauseMenu {
	//NSLog(@"closing pause...");

	[littleButton setHidden:YES];
	[littleButton removeTarget:self action:@selector(closePauseMenu) forControlEvents:UIControlEventTouchUpInside];

	[bigButton setHidden:YES];
	[bigButton removeTarget:self action:@selector(startNewGame) forControlEvents:UIControlEventTouchUpInside];

	[popupView setHidden:YES];
	[popupView setUserInteractionEnabled:NO];

	[gameView setUserInteractionEnabled:YES];
	[[scrollView viewWithTag:101010] removeFromSuperview];
}


- (void)openGameOverLost {
	//NSLog(@"game over... you lost.");
	
	gameOverLostViewIsDisplayed = YES;
	[gameView setUserInteractionEnabled:NO];
	[gameOverLostImageView setHidden:NO];
	[gameBoardView setUserInteractionEnabled:NO];
	[[self view] bringSubviewToFront:gameOverLostImageView];
}


- (void)closeGameOverLost {
	//NSLog(@"closing gameOverLost...");
	
	gameOverLostViewIsDisplayed = NO;
	
	[gameOverLostImageView setHidden:YES];
	[gameView setUserInteractionEnabled:YES];
	[gameBoardView setUserInteractionEnabled:YES];
	
	[self startNewGame];
}


- (void)openGameOverWon {
	//NSLog(@"game over... you won!");

	gameOverWonViewIsDisplayed = YES;

	[gameView setUserInteractionEnabled:NO];
	[gameBoardView setUserInteractionEnabled:NO];

	[(UILabel *) [gameOverWonImageView viewWithTag:777] setText:[NSString stringWithFormat:@"%i",[gameState score]]];
	[gameOverWonImageView setHidden:NO];
	[gameBoardView setUserInteractionEnabled:NO];
	[[self view] bringSubviewToFront:gameOverWonImageView];
}


- (void)closeGameOverWon {
	//NSLog(@"closing gameOverWon...starting new game");

	gameOverWonViewIsDisplayed = NO;

	[gameOverWonImageView setHidden:YES];
	[gameView setUserInteractionEnabled:YES];
	[gameBoardView setUserInteractionEnabled:YES];

	[self startNewGame];
}


- (void)openHelpMenu {
	//NSLog(@"showing help...");
	//id appDelegate = [[UIApplication sharedApplication] delegate];

	[popupView setUserInteractionEnabled:YES];
	[gameView setUserInteractionEnabled:NO];

	[popupView setHidden:NO];
	[[self view] bringSubviewToFront:popupView];
	[popupView bringSubviewToFront:littleButton];
	[littleButton setTitle:@"Return To Game" forState:UIControlStateNormal];
	[littleButton setHidden:NO];
	[littleButton addTarget:self action:@selector(closeHelpMenu) forControlEvents:UIControlEventTouchUpInside];

	for ( id subView in helpSubviews ) {
		[scrollView addSubview:subView];
	}
}


- (void)closeHelpMenu {
	//NSLog(@"closing help...");

	for ( id subView in helpSubviews ) {
		[subView removeFromSuperview];
	}

	[littleButton setHidden:YES];
	[littleButton removeTarget:self action:@selector(closeHelpMenu) forControlEvents:UIControlEventTouchUpInside];
	[popupView setHidden:YES];
	[popupView setUserInteractionEnabled:NO];
	
	[gameView setUserInteractionEnabled:YES];
}


- (void)openInitialMenu {
	//NSLog(@"showing main menu...");

	[popupView setUserInteractionEnabled:YES];
	[gameView setUserInteractionEnabled:NO];

	[popupView setHidden:NO];
	[popupView bringSubviewToFront:littleButton];

	[littleButton setTitle:@"Return To Game" forState:UIControlStateNormal];
	[littleButton setHidden:NO];
	[littleButton addTarget:self action:@selector(closeHelpMenu) forControlEvents:UIControlEventTouchUpInside];
}


- (void)closeInitialMenu {
	//NSLog(@"closing main menu...");

	[littleButton setHidden:YES];
	[littleButton removeTarget:self action:@selector(closeHelpMenu) forControlEvents:UIControlEventTouchUpInside];
	[popupView setHidden:YES];
	[popupView setUserInteractionEnabled:NO];

	[gameView setUserInteractionEnabled:YES];
}


#pragma mark -
#pragma mark touch methods


- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
	if ( [gameState askingQuestion] ) {
		UITouch *touch      =  [touches anyObject];
		startTouchPosition  =  [touch locationInView:self.view];
	}

	// DEFAULT
	//NSLog(@"stop touching me!");
}


-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
	if ( questionAnsweredViewIsDisplayed ) {
		questionAnsweredViewIsDisplayed = NO;
		[self closeQuestionView];
		return;
	}
	else if ( gameOverWonViewIsDisplayed ) {
		[self closeGameOverWon];
		return;
	}
	else if ( gameOverLostViewIsDisplayed ) {
		[self closeGameOverLost];
		return;
	}
	else if ( ! [gameState askingQuestion] ) {
		return;
	}

	UITouch *touch  =  touches.anyObject;
	self.currentTouchPosition  =  [touch locationInView:self.view];
	
	// swipe tracks correctly!
	if ( fabsf( startTouchPosition.x - self.currentTouchPosition.x ) >= HORIZONTAL_SWIPE_DRAG_MIN &&
		fabsf( startTouchPosition.y - self.currentTouchPosition.y ) <= VERTICAL_SWIPE_DRAG_MAX ) {
		if ( self.startTouchPosition.x < self.currentTouchPosition.x ) {
			[questionView slideAnswerRight];
		}
		else {
			[questionView slideAnswerLeft];
		}
		//NSLog(@"We have a swipe!");
	}
	else {
		if ( currentTouchPosition.x > 160 ) {
			[questionView slideAnswerLeft];
		}
		else {
			[questionView slideAnswerRight];
		}
	}
}


#pragma mark -
#pragma mark memory crap


- (void)releaseGameTileImages {
	//NSLog(@"releasing gameTile images");
	for ( id image in tileImages ) {
		[image removeFromSuperview];
		//NSLog(@"retain %i", [image retainCount]);
	}
	[tileImages removeAllObjects];
}


- (void)didReceiveMemoryWarning {
	NSLog(@"GameViewController didReceiveMemoryWarning!!!");

	// Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
	
	// Release any cached data, images, etc that aren't in use. Or not.
}


- (void)viewDidUnload {
	[self dealloc];
}


- (void)dealloc {
	[gameState release];

	[buttonLeft release];
	[buttonRight release];
	[buttonUp release];
	[buttonDown release];

	[gameView release];
	[tileImages release];
	[starImageView release];
	[correctImageView release];
	[incorrectImageView release];
	[gameOverWonImageView release];

	[popupView release];
	[scrollView release];
	[bigButton release];
	[littleButton release];

    [super dealloc];
}


@end
